//============================================================================
// Name        : rscj.cpp
// Author      : Bob
// Version     :0
// Copyright   : Your copyright notice
// Description : your mom
//============================================================================


#include "stdafx.h"
#include <vector>
#include <ctime>
#include "u_i.h"
#include <boost/lexical_cast.hpp>

using namespace std;
const int threadnumber=8;
const long double deltai=0.01;
 long double deltat=0.01;
//const long double deltatmax=0.1;
//const long double deltatmin=0.01;
//const long double betac=10;
//const long double omega=2.85;
//const long double imicro=0;
 const double deltab=1;
//u_i uiobj;
void write(vector<long double>& data1,vector<long double>& data2,vector<long double>& data3, int& n);
void write(vector<long double>& data1,vector<long double>& data2, int n,string filename);
void writematrix(vector<long double>& x,vector<long double>& y,vector<vector<long double> >& data);
void writematrix2(vector<long double>& x,vector<long double>& y,vector<vector<long double> >& data);
double benchmark(int threadcount);
double least_squares(vector<long double>& data1,vector<long double>& data2);
void calcdata();
void calcdata2();


int main() {
	
	clock_t begin = clock();

	/*vector<long double> num;
	vector<long double> time;
	for(int i=1;i<15;++i){
		num.push_back(i);
		time.push_back(benchmark(i));
		cout<<num.back()<<" "<<time.back()<<endl;
	}
	int temp=num.size();
	write(num,time,temp,"benchmark.txt");
	*/









	//calcdata();
	calcdata2();
	clock_t end = clock();
	double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
	cout<<elapsed_secs<<endl;
	char i;
	cin>>i;

//	return elapsed_secs;
}

double least_squares(vector<long double>& data1,vector<long double>& data2){
long double temp=0;
for(int i=0;i<data1.size();++i){
temp+=pow((data1[i]-data2[i]),2);
}
return temp;
}

double benchmark(int threadcount){
	clock_t begin = clock();
	vector<u_i> uiobj;
	int n,l=0;
	for(int i=0;i<threadcount;++i){
		uiobj.push_back(u_i(1,1));
		uiobj[i].setiac(0);
		uiobj[i].seth(deltat);
		uiobj[i].setimin(0);
		uiobj[i].setimax(5);
	}
	for(int i=0;i<threadcount;++i){
		uiobj[i].start();
	}
	n=threadcount-1;
	
	while(n<100){
		for(int i=0;i<threadcount;++i){
			if(uiobj[i].getStatus()==myThread::Stat::FINISHED && n<100){
			++n;
			uiobj[i].setbetac(1);
			uiobj[i].start();
			}
			
		}
		boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}

	int finished=0;
	int pending=0;
	while(finished<threadcount && pending!=threadcount){
		pending=0;
	for(int i=0; i<threadcount;++i){
		if(uiobj[i].getStatus()==myThread::Stat::FINISHED){
		++finished;
		uiobj[i].setStatus(myThread::Stat::PENDING);
		}else if(uiobj[i].getStatus()==myThread::Stat::PENDING){
			++pending;
		}
	}
	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}
	clock_t end = clock();
	double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
	return elapsed_secs;

}

void calcdata(){
vector<long double> betac;
	vector<double> omega;
	vector<double> iac;
	vector<vector<long double> > data;
	vector<long double> current;
	//data.resize(5/deltai);

	vector<u_i> uiobj;
	betac.resize(1);
	betac[0]=deltab;
	omega.resize(1);
	omega[0]=1;
	iac.resize(1);
	iac[0]=0;
	int n,nmax=0;
	nmax=1;
	while(betac.back()<5){
		//++nmax;
		long double temp=betac.back();
		betac.push_back(temp+deltab);
		omega.push_back(1);
		iac.push_back(0);
		//cout<<betac.back()<<endl;
	}
	

	string test;

	for(int i=0;i<threadnumber;++i){
		n=i;
		uiobj.push_back(u_i(betac[i],omega[i]));
		uiobj.at(i).setiac(iac[i]);
		uiobj[i].seth(deltat);
		uiobj[i].setimin(0);
		uiobj[i].setimax(5);
		uiobj[i].setfilename("data\\"+boost::lexical_cast<std::string>(betac[i])+".txt");
		
		
	}
	for(int i=0;i<threadnumber;++i){
		uiobj[i].start();
	}
	while(n<betac.size()-1){
	for(int i=0; i<threadnumber;++i ){
		if(uiobj[i].getStatus()==myThread::Stat::FINISHED && (n<betac.size()-1)){
		++n;
		data.push_back(uiobj[i].U);
		data.back().push_back(uiobj[i].getbetac());
		uiobj[i].write();
		float status=((((float)n)/((float)betac.size())))*100.0;
		cout<<status<<"%"<<endl;
		uiobj[i].setbetac(betac[n]);
		//cout<<betac[n]<<" "<<uiobj[i].getbetac()<<" "<<uiobj[i].getfilename()<<endl;
		uiobj[i].setfilename("data\\"+boost::lexical_cast<std::string>(betac[n])+".txt");
		
		uiobj[i].start();
		}
	}
	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}
	
	int finished=0;
	int pending=0;
	while(finished<threadnumber && pending!=threadnumber){
		pending=0;
	for(int i=0; i<threadnumber;++i){
		if(uiobj[i].getStatus()==myThread::Stat::FINISHED){
		++finished;
		uiobj[i].write();
		data.push_back(uiobj[i].U);
		uiobj[i].setStatus(myThread::Stat::PENDING);
		data.back().push_back(uiobj[i].getbetac());
		}else if(uiobj[i].getStatus()==myThread::Stat::PENDING){
			++pending;
		}
	}
	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}


	current=uiobj[0].I;
	vector<long double> betacunsrt;
	for(int i=0;i<data.size();++i){
		betacunsrt.push_back(data[i][data[i].size()-1]);
	}
	writematrix(current,betacunsrt,data);
	
}
void calcdata2(){
vector<long double> smax;
	vector<int> pos;
	vector<long double> smaxtemp;
	vector<double> omega;
	vector<double> iac;
	vector<vector<long double> > data;
	vector<long double> current;
	//data.resize(5/deltai);
	int temp=0;
	vector<long double> betac;
	betac.push_back(0.1);
	vector<vector<long double>> smaxdata;
	//smax.resize(1);
	//smax[0]=50;
	//smax.push_back(100);
	//while(smax.back()<=2000){
	//	//++nmax;
	//	long double temp=smax.at(smax.size()-2);
	//	smax.push_back((temp+100)/2);
	//	smax.push_back(temp+100);
	//	omega.push_back(1);
	//	iac.push_back(0);
	//	//cout<<betac.back()<<endl;
	//}
	smax.push_back(10000);
	for(double temp=50;temp<=2000;temp=temp+50){
		//smax.push_back(temp/2.0);
		smax.push_back(temp);
	}

	while(betac.back()<11){
		data.clear();
	vector<u_i> uiobj;
	
	omega.resize(1);
	omega[0]=1;
	iac.resize(1);
	iac[0]=0;
	int n,nmax=0;
	nmax=1;
	
	data.resize(smax.size());

	string test;
	pos.clear();
	pos.resize(0);
	uiobj.clear();
	uiobj.resize(0);
	for(int i=0;i<threadnumber && i<smax.size();++i){
		n=i;
		uiobj.push_back(u_i(betac.back(),1));
		pos.push_back(i);
		uiobj[i].setiac(0);
		uiobj[i].seth(deltat);
		uiobj[i].setsmax(smax[i]);
		uiobj[i].setimin(0);
		uiobj[i].setimax(5);
		uiobj[i].setfilename("data\\"+boost::lexical_cast<std::string>(smax[i])+".txt");
		
		
	}
	for(int i=0;i<threadnumber && i<smax.size();++i){
		uiobj[i].start();
	}
	while(n<smax.size()-1){
	for(int i=0; i<threadnumber && i<smax.size();++i ){
		if(uiobj[i].getStatus()==myThread::Stat::FINISHED && (n<smax.size()-1)){
			//uiobj[i].write();
		++n;
		temp=0;
		
		data.at(pos.at(i))=(uiobj[i].U);
		//data.back().push_back(uiobj[j].getsmax());
		//uiobj[i].write();
		float status=((((float)n)/((float)smax.size())))*100.0;
		cout<<status<<"%"<<endl;
		uiobj[i].setsmax(smax[n]);
		pos.at(i)=n;
		//cout<<betac[n]<<" "<<uiobj[i].getbetac()<<" "<<uiobj[i].getfilename()<<endl;
		uiobj[i].setfilename("data\\"+boost::lexical_cast<std::string>(smax[n])+".txt");
		
		uiobj[i].start();
		}
	}
	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}
	
	int finished=0;
	int pending=0;
	while(finished<uiobj.size() && pending!=threadnumber){
		pending=0;
	for(int i=0; i<threadnumber && i<smax.size();++i){
		if(uiobj[i].getStatus()==myThread::Stat::FINISHED){
			//uiobj[i].write();
		++finished;
		//uiobj[i].write();
		temp=0;
		
		data.at(pos.at(i))=(uiobj[i].U);
		uiobj[i].setStatus(myThread::Stat::PENDING);
		//data.at(temp).push_back(uiobj[i].getbetac());
		}else if(uiobj[i].getStatus()==myThread::Stat::PENDING){
			++pending;
		}
	}
	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
	}


	current=uiobj[0].I;
	//vector<long double> betacunsrt;
	//for(int i=0;i<data.size();++i){
		//betacunsrt.push_back(data[i][data[i].size()-1]);
	//}
	//writematrix(current,smax,data);
	smaxtemp.clear();
	vector<long double> temp;
	for(int i=0;i<smax.size();++i){
		temp.push_back(least_squares(data.at(i),data.at(0)));
		smaxtemp.push_back(smax.at(i));
	}
	smaxdata.push_back(temp);
	betac.push_back(betac.back()+0.1);
	for(int i=0;i<uiobj.size();++i){
		uiobj.at(i).detach();
		uiobj.at(i).~u_i();
	}

	}
	betac.resize(betac.size()-1);
	writematrix(smaxtemp,betac,smaxdata);
	writematrix2(smaxtemp,betac,smaxdata);
	
}

void write(vector<long double>& data1,vector<long double>& data2,vector<long double>& data3, int& n){
	fstream datei;
	datei.open("data.txt", ios::out);
	for(int i=0;i<n;i++){
		datei<<data1[i]<<" "<<data2[i]<<" "<<data3[i]<<endl;
	}
	datei.close();
}

void write(vector<long double>& data1,vector<long double>& data2, int n,string filename){
	fstream datei;
	datei.open(filename, ios::out);
	for(int i=0;i<n;i++){
		datei<<data1[i]<<" "<<data2[i]<<endl;
	}
	datei.close();
}

void writematrix(vector<long double>& x,vector<long double>& y,vector<vector<long double> >& data){
		std::fstream datei;
	datei.open("data.txt", std::ios::out);

	datei<<0.0<<"\t";
		for(int j=0;j<y.size();++j){
		datei<<y[j]<<"\t";
		
		}
		datei<<endl;

		for(int i=0;i<data.at(0).size();++i){
	datei<<x[i]<<"\t";
		for(int j=0;j<data.size();++j){
		datei<<data[j][i]<<"\t";
		
		}
		datei<<endl;
	}
	datei.close();


}
void writematrix2(vector<long double>& x,vector<long double>& y,vector<vector<long double> >& data){
		std::fstream datei;
	datei.open("datamat.txt", std::ios::out);

	for(int i=0;i<y.size() && i<data.size();++i){
		for(int j=0;j<x.size() && j<data.at(i).size();++j){
			datei<<x.at(j)<<" "<<y.at(i)<<" "<<data.at(i).at(j)<<endl;
		}
	}

	datei.close();


}


